use chrono::Local;
use fern::Dispatch;
use log::{error, info, warn};
use std::fs;
use std::path::Path;

/// 初始化日志系统
/// 
/// 日志格式遵循RFC 5424标准的简化版本：
/// TIMESTAMP LEVEL [APP-NAME:PROCID] MESSAGE
/// 
/// 例如：
/// 2024-01-15 14:30:25.123 INFO [ctp_trade:1234] User login successful: user_id=12345
/// 2024-01-15 14:30:26.456 ERROR [ctp_trade:1234] Order insertion failed: order_id=67890, error=insufficient_funds
pub fn init_logger() -> Result<(), fern::InitError> {
    // 确保logs目录存在
    let logs_dir = "logs";
    if !Path::new(logs_dir).exists() {
        if let Err(e) = fs::create_dir_all(logs_dir) {
            eprintln!("Failed to create logs directory: {}", e);
            // 直接返回IO错误，让fern处理
            return Err(fern::InitError::from(e));
        }
    }

    // 获取当前日期用于日志文件名
    let today = Local::now().format("%Y-%m-%d").to_string();
    let log_file = format!("{}/ctp_trade_{}.txt", logs_dir, today);

    Dispatch::new()
        // 设置日志级别
        .level(log::LevelFilter::Info)
        // 设置日志格式 - 遵循标准格式
        .format(|out, message, record| {
            out.finish(format_args!(
                "{} {} [{}:{}] {}",
                Local::now().format("%Y-%m-%d %H:%M:%S%.3f"),
                record.level(),
                record.target(),
                std::process::id(),
                message
            ))
        })
        // 输出到控制台（开发环境）
        .chain(std::io::stdout())
        // 输出到文件
        .chain(fern::log_file(&log_file)?)
        .apply()?;

    info!("Logger initialized successfully, log file: {}", log_file);
    Ok(())
}

/// 记录用户登录日志
pub fn log_user_login(user_id: &str, broker_id: &str, success: bool, error_msg: Option<&str>) {
    if success {
        info!(
            "User login successful: user_id={}, broker_id={}",
            user_id, broker_id
        );
    } else {
        error!(
            "User login failed: user_id={}, broker_id={}, error={}",
            user_id,
            broker_id,
            error_msg.unwrap_or("unknown")
        );
        
        // 播放错误提示音
        crate::audio_manager::play_error_notification();
    }
}

/// 记录用户登出日志
pub fn log_user_logout(user_id: &str, broker_id: &str, success: bool, error_msg: Option<&str>) {
    if success {
        info!(
            "User logout successful: user_id={}, broker_id={}",
            user_id, broker_id
        );
    } else {
        error!(
            "User logout failed: user_id={}, broker_id={}, error={}",
            user_id,
            broker_id,
            error_msg.unwrap_or("unknown")
        );
    }
}

/// 记录市场数据查询日志
pub fn log_market_data_query(instrument_ids: &[String], success: bool, error_msg: Option<&str>) {
    if success {
        info!(
            "Market data query successful: instruments=[{}]",
            instrument_ids.join(", ")
        );
    } else {
        error!(
            "Market data query failed: instruments=[{}], error={}",
            instrument_ids.join(", "),
            error_msg.unwrap_or("unknown")
        );
    }
}

/// 记录合约查询日志
pub fn log_instrument_query(exchange_id: Option<&str>, success: bool, count: Option<usize>, error_msg: Option<&str>) {
    if success {
        info!(
            "Instrument query successful: exchange_id={}, count={}",
            exchange_id.unwrap_or("all"),
            count.unwrap_or(0)
        );
    } else {
        error!(
            "Instrument query failed: exchange_id={}, error={}",
            exchange_id.unwrap_or("all"),
            error_msg.unwrap_or("unknown")
        );
    }
}

/// 记录挂单日志
pub fn log_order_insert(
    order_ref: &str,
    instrument_id: &str,
    direction: &str,
    volume: i32,
    price: f64,
    success: bool,
    error_msg: Option<&str>,
) {
    if success {
        info!(
            "Order insertion successful: order_ref={}, instrument_id={}, direction={}, volume={}, price={}",
            order_ref, instrument_id, direction, volume, price
        );
    } else {
        error!(
            "Order insertion failed: order_ref={}, instrument_id={}, direction={}, volume={}, price={}, error={}",
            order_ref,
            instrument_id,
            direction,
            volume,
            price,
            error_msg.unwrap_or("unknown")
        );
        
        // 播放错误提示音
        crate::audio_manager::play_error_notification();
    }
}

/// 记录撤单日志
pub fn log_order_cancel(
    order_ref: &str,
    instrument_id: &str,
    exchange_id: &str,
    success: bool,
    error_msg: Option<&str>,
) {
    if success {
        info!(
            "Order cancellation successful: order_ref={}, instrument_id={}, exchange_id={}",
            order_ref, instrument_id, exchange_id
        );
    } else {
        error!(
            "Order cancellation failed: order_ref={}, instrument_id={}, exchange_id={}, error={}",
            order_ref,
            instrument_id,
            exchange_id,
            error_msg.unwrap_or("unknown")
        );
        
        // 播放错误提示音
        crate::audio_manager::play_error_notification();
    }
}

/// 记录账户查询日志
pub fn log_account_query(broker_id: &str, investor_id: &str, success: bool, error_msg: Option<&str>) {
    if success {
        info!(
            "Account query successful: broker_id={}, investor_id={}",
            broker_id, investor_id
        );
    } else {
        error!(
            "Account query failed: broker_id={}, investor_id={}, error={}",
            broker_id,
            investor_id,
            error_msg.unwrap_or("unknown")
        );
    }
}

/// 记录持仓查询日志
pub fn log_position_query(
    broker_id: &str,
    investor_id: &str,
    instrument_id: Option<&str>,
    success: bool,
    error_msg: Option<&str>,
) {
    if success {
        info!(
            "Position query successful: broker_id={}, investor_id={}, instrument_id={}",
            broker_id,
            investor_id,
            instrument_id.unwrap_or("all")
        );
    } else {
        error!(
            "Position query failed: broker_id={}, investor_id={}, instrument_id={}, error={}",
            broker_id,
            investor_id,
            instrument_id.unwrap_or("all"),
            error_msg.unwrap_or("unknown")
        );
    }
}

/// 记录API异常日志
pub fn log_api_error(api_name: &str, function_name: &str, error_msg: &str) {
    error!(
        "API error occurred: api={}, function={}, error={}",
        api_name, function_name, error_msg
    );
    
    // 播放错误提示音
    crate::audio_manager::play_error_notification();
}

/// 记录系统警告日志
pub fn log_warning(component: &str, message: &str) {
    warn!("System warning: component={}, message={}", component, message);
}

/// 记录系统信息日志
pub fn log_info(component: &str, message: &str) {
    info!("System info: component={}, message={}", component, message);
}

/// 记录应用启动日志
pub fn log_app_start() {
    info!("Application starting: version={}, process_id={}", 
          env!("CARGO_PKG_VERSION"), std::process::id());
}

/// 记录应用关闭日志
pub fn log_app_shutdown(reason: &str) {
    info!("Application shutting down: reason={}, process_id={}", 
          reason, std::process::id());
}

/// 记录Panic异常
pub fn log_panic(panic_info: &str, location: Option<&str>) {
    error!("PANIC occurred: info={}, location={}, process_id={}", 
           panic_info, location.unwrap_or("unknown"), std::process::id());
    
    // 播放错误提示音
    crate::audio_manager::play_error_notification();
}

/// 记录Tauri事件
pub fn log_tauri_event(event_type: &str, details: &str) {
    info!("Tauri event: type={}, details={}", event_type, details);
}

/// 记录窗口事件
pub fn log_window_event(window_label: &str, event_type: &str, details: &str) {
    info!("Window event: window={}, type={}, details={}", window_label, event_type, details);
}

/// 记录内存使用情况
pub fn log_memory_usage() {
    if let Ok(usage) = get_memory_usage() {
        info!("Memory usage: rss={}MB, virtual={}MB", 
              usage.rss / 1024 / 1024, usage.virtual_memory / 1024 / 1024);
    }
}

/// 记录致命错误
pub fn log_fatal_error(error: &str, context: &str) {
    error!("FATAL ERROR: error={}, context={}, process_id={}", 
           error, context, std::process::id());
    
    // 播放错误提示音
    crate::audio_manager::play_error_notification();
}

/// 获取内存使用情况的结构体
#[derive(Debug)]
struct MemoryUsage {
    rss: u64,
    virtual_memory: u64,
}

/// 获取当前进程的内存使用情况
fn get_memory_usage() -> Result<MemoryUsage, Box<dyn std::error::Error>> {
    #[cfg(windows)]
    {
        use std::mem;
        
        // Windows API 调用获取内存信息
        extern "system" {
            fn GetCurrentProcess() -> *mut std::ffi::c_void;
            fn GetProcessMemoryInfo(
                process: *mut std::ffi::c_void,
                pmc: *mut ProcessMemoryCounters,
                cb: u32,
            ) -> i32;
        }
        
        #[repr(C)]
        struct ProcessMemoryCounters {
            cb: u32,
            page_fault_count: u32,
            peak_working_set_size: usize,
            working_set_size: usize,
            quota_peak_paged_pool_usage: usize,
            quota_paged_pool_usage: usize,
            quota_peak_non_paged_pool_usage: usize,
            quota_non_paged_pool_usage: usize,
            pagefile_usage: usize,
            peak_pagefile_usage: usize,
        }
        
        unsafe {
            let process = GetCurrentProcess();
            let mut pmc: ProcessMemoryCounters = mem::zeroed();
            pmc.cb = mem::size_of::<ProcessMemoryCounters>() as u32;
            
            if GetProcessMemoryInfo(process, &mut pmc, pmc.cb) != 0 {
                Ok(MemoryUsage {
                    rss: pmc.working_set_size as u64,
                    virtual_memory: pmc.pagefile_usage as u64,
                })
            } else {
                Err("Failed to get memory info".into())
            }
        }
    }
    
    #[cfg(not(windows))]
    {
        // 对于非Windows系统，返回模拟数据
        Ok(MemoryUsage {
            rss: 0,
            virtual_memory: 0,
        })
    }
}

/// 记录订单验证错误日志
pub fn log_validation_error(error_type: &str, instrument_id: &str, error_msg: &str) {
    error!(
        "Order validation failed: error_type={}, instrument={}, message={}",
        error_type, instrument_id, error_msg
    );
}

/// 记录订单验证结果日志
pub fn log_order_validation(instrument_id: &str, success: bool, error_summary: Option<&str>) {
    if success {
        info!(
            "Order validation successful: instrument={}",
            instrument_id
        );
    } else {
        error!(
            "Order validation failed: instrument={}, errors={}",
            instrument_id,
            error_summary.unwrap_or("unknown")
        );
    }
}
